
/**
 * 本地存储统一管理工具
 * 支持localStorage/sessionStorage/Cookie三种存储方式
 */

// 存储类型枚举
const StorageType = {
    LOCAL: 'local',
    SESSION: 'session',
    COOKIE: 'cookie'
}

// 过期时间单位
const ExpireUnit = {
    DAY: 'd',
    HOUR: 'h',
    MINUTE: 'm',
    SECOND: 's'
}

class StorageManager {
    constructor(type = StorageType.LOCAL) {
        this.storageType = type
    }

    /**
     * 设置存储项
     * @param {string} key 键名
     * @param {any} value 键值
     * @param {Object} options 配置项 {
     *   expires: 过期时间值,
     *   unit: 时间单位,
     *   path: Cookie路径
     * }
     */
    set(key, value, options = {}) {
        const { expires, unit = ExpireUnit.DAY, path = '/' } = options
        const storageValue = {
            data: value,
            timestamp: Date.now(),
            expires: expires ? this._calculateExpires(expires, unit) : null
        }

        switch (this.storageType) {
            case StorageType.LOCAL:
                localStorage.setItem(key, JSON.stringify(storageValue))
                break
            case StorageType.SESSION:
                sessionStorage.setItem(key, JSON.stringify(storageValue))
                break
            case StorageType.COOKIE:
                document.cookie = this._buildCookie(
                    key,
                    JSON.stringify(storageValue),
                    expires,
                    unit,
                    path
                )
                break
        }
    }

    /**
     * 获取存储项
     * @param {string} key 键名
     * @returns {any} 存储的值
     */
    get(key) {
        let storedValue = null

        switch (this.storageType) {
            case StorageType.LOCAL:
                storedValue = localStorage.getItem(key)
                break
            case StorageType.SESSION:
                storedValue = sessionStorage.getItem(key)
                break
            case StorageType.COOKIE:
                storedValue = this._getCookie(key)
                break
        }

        if (!storedValue) return null

        try {
            const parsedValue = JSON.parse(storedValue)
            // 检查过期时间
            if (parsedValue.expires && Date.now() > parsedValue.expires) {
                this.remove(key)
                return null
            }
            return parsedValue.data
        } catch (e) {
            return storedValue // 兼容非JSON格式数据
        }
    }

    /**
     * 移除存储项
     * @param {string} key 键名
     */
    remove(key) {
        switch (this.storageType) {
            case StorageType.LOCAL:
                localStorage.removeItem(key)
                break
            case StorageType.SESSION:
                sessionStorage.removeItem(key)
                break
            case StorageType.COOKIE:
                document.cookie = `${key}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
                break
        }
    }

    /**
     * 清空当前类型存储
     */
    clear() {
        switch (this.storageType) {
            case StorageType.LOCAL:
                localStorage.clear()
                break
            case StorageType.SESSION:
                sessionStorage.clear()
                break
            case StorageType.COOKIE:
                document.cookie.split(';').forEach(cookie => {
                    const eqPos = cookie.indexOf('=')
                    const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie
                    document.cookie = `${name.trim()}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`
                })
                break
        }
    }

    // 私有方法：计算过期时间戳
    _calculateExpires(value, unit) {
        const now = Date.now()
        switch (unit) {
            case ExpireUnit.DAY:
                return now + value * 24 * 60 * 60 * 1000
            case ExpireUnit.HOUR:
                return now + value * 60 * 60 * 1000
            case ExpireUnit.MINUTE:
                return now + value * 60 * 1000
            case ExpireUnit.SECOND:
                return now + value * 1000
            default:
                return now + value * 24 * 60 * 60 * 1000
        }
    }

    // 私有方法：构建Cookie字符串
    _buildCookie(key, value, expires, unit, path) {
        let cookieStr = `${key}=${encodeURIComponent(value)}; path=${path}`
        if (expires) {
            const date = new Date(this._calculateExpires(expires, unit))
            cookieStr += `; expires=${date.toUTCString()}`
        }
        return cookieStr
    }

    // 私有方法：获取Cookie值
    _getCookie(key) {
        const cookies = document.cookie.split(';')
        for (let cookie of cookies) {
            const [cookieKey, cookieValue] = cookie.split('=')
            if (cookieKey.trim() === key) {
                return decodeURIComponent(cookieValue)
            }
        }
        return null
    }
}

// 导出三种存储类型的实例
export const local = new StorageManager(StorageType.LOCAL)
export const session = new StorageManager(StorageType.SESSION)
export const cookie = new StorageManager(StorageType.COOKIE)

// 默认导出localStorage实例
export default local
